home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / SRC / HOARDDLL.ZIP / 3rdParty / hoard / libhoard-2.0.2 / processheap.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-22  |  5.4 KB  |  210 lines

  1. ///-*-C++-*-//////////////////////////////////////////////////////////////////
  2. //
  3. // Hoard: A Fast, Scalable, and Memory-Efficient Allocator
  4. //        for Shared-Memory Multiprocessors
  5. // Contact author: Emery Berger, http://www.cs.utexas.edu/users/emery
  6. //
  7. // Copyright (c) 1998-2000, The University of Texas at Austin.
  8. //
  9. // This library is free software; you can redistribute it and/or modify
  10. // it under the terms of the GNU Library General Public License as
  11. // published by the Free Software Foundation, http://www.fsf.org.
  12. //
  13. // This library is distributed in the hope that it will be useful, but
  14. // WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19.  
  20. #include <string.h>
  21. #include <stdio.h>
  22.  
  23. #include "config.h"
  24.  
  25. #if USE_PRIVATE_HEAPS
  26. #include "privateheap.h"
  27. #define HEAPTYPE privateHeap
  28. #else
  29. #define HEAPTYPE threadHeap
  30. #include "threadheap.h"
  31. #endif
  32.  
  33. #include "processheap.h"
  34.  
  35.  
  36. processHeap::processHeap (void)
  37.   : _buffer (NULL),
  38.     _bufferCount (0)
  39. #if HEAP_FRAG_STATS
  40.   , _currentAllocated (0),
  41.   _currentRequested (0),
  42.   _maxAllocated (0),
  43.   _inUseAtMaxAllocated (0),
  44.   _maxRequested (0)
  45. #endif
  46. {
  47.   int i;
  48.   // The process heap is heap 0.
  49.   setIndex (0);
  50.   for (i = 0; i < MAX_HEAPS; i++) {
  51.     // Set every thread's process heap to this one.
  52.     theap[i].setpHeap (this);
  53.     // Set every thread heap's index.
  54.     theap[i].setIndex (i + 1);
  55.   }
  56. #if HEAP_LOG
  57.   for (i = 0; i < MAX_HEAPS + 1; i++) {
  58.     char fname[255];
  59.     sprintf (fname, "log%d", i);
  60.     unlink (fname);
  61.     _log[i].open (fname);
  62.   }
  63. #endif
  64. #if HEAP_FRAG_STATS
  65.   hoardLockInit (_statsLock);
  66. #endif
  67.   hoardLockInit (_bufferLock);
  68. }
  69.  
  70.  
  71. // Print out statistics information.
  72. void processHeap::stats (void) {
  73. #if HEAP_STATS
  74.   int umax = 0;
  75.   int amax = 0;
  76.   for (int j = 0; j < MAX_HEAPS; j++) {
  77.     for (int i = 0; i < SIZE_CLASSES; i++) {
  78.       amax += theap[j].maxAllocated(i) * sizeFromClass (i);
  79.       umax += theap[j].maxInUse(i) * sizeFromClass (i);
  80.     }
  81.   }
  82.   printf ("Amax <= %d, Umax <= %d\n", amax, umax);
  83. #if HEAP_FRAG_STATS
  84.   amax = getMaxAllocated();
  85.   umax = getMaxRequested();
  86.   printf ("Maximum allocated = %d\nMaximum in use = %d\nIn use at max allocated = %d\n", amax, umax, getInUseAtMaxAllocated());
  87.   printf ("Still in use = %d\n", _currentRequested);
  88.   printf ("Fragmentation (3) = %f\n", (float) amax / (float) getInUseAtMaxAllocated());
  89.   printf ("Fragmentation (4) = %f\n", (float) amax / (float) umax);
  90. #endif
  91.  
  92. #endif // HEAP_STATS  
  93. #if HEAP_LOG
  94.   printf ("closing logs.\n");
  95.   fflush (stdout);
  96.   for (int i = 0; i < MAX_HEAPS + 1; i++) {
  97.     _log[i].close();
  98.   }
  99. #endif
  100. }
  101.  
  102.  
  103.  
  104. #if HEAP_FRAG_STATS
  105. void processHeap::setAllocated (int requestedSize,
  106.                 int actualSize)
  107. {
  108.   hoardLock (_statsLock);
  109.   _currentRequested += requestedSize;
  110.   _currentAllocated += actualSize;
  111.   if (_currentRequested > _maxRequested) {
  112.     _maxRequested = _currentRequested;
  113.   }
  114.   if (_currentAllocated > _maxAllocated) {
  115.     _maxAllocated = _currentAllocated;
  116.     _inUseAtMaxAllocated = _currentRequested;
  117.   }
  118.   hoardUnlock (_statsLock);
  119. }
  120.  
  121.  
  122. void processHeap::setDeallocated (int requestedSize,
  123.                   int actualSize)
  124. {
  125.   hoardLock (_statsLock);
  126.   _currentRequested -= requestedSize;
  127.   _currentAllocated -= actualSize;
  128.   hoardUnlock (_statsLock);
  129. }
  130. #endif
  131.  
  132.  
  133. // free (ptr, pheap):
  134. //   inputs: a pointer to an object allocated by malloc().
  135. //   side effects: returns the block to the object's superblock;
  136. //                 updates the thread heap's statistics;
  137. //                 may release the superblock to the process heap.
  138.  
  139. void processHeap::free (void * ptr)
  140. {
  141.  
  142.   // Return if ptr is 0.
  143.   // This is the behavior prescribed by the standard.
  144.   if (ptr == 0) {
  145.     return;
  146.   }
  147.  
  148.   // Find the block and superblock corresponding to this ptr.
  149.  
  150.   block * b = (block *) ptr - 1;
  151.   assert (b->isValid());
  152.  
  153.   // Check to see if this block came from a memalign() call.
  154.   if (((unsigned long) b->getNext() & 1) == 1) {
  155.     // It did. Set the block to the actual block header.
  156.     b = (block *) ((unsigned long) b->getNext() & ~1);
  157.     assert (b->isValid());
  158.   }    
  159.  
  160.   b->markFree();
  161.  
  162.   superblock * sb = b->getSuperblock();
  163.   assert (sb);
  164.   assert (sb->isValid());
  165.  
  166.   const int sizeclass = sb->getBlockSizeClass();
  167.  
  168.   //
  169.   // Return the block to the superblock,
  170.   // find the heap that owns this superblock
  171.   // and update its statistics.
  172.   //
  173.  
  174.   hoardHeap * owner;
  175.  
  176.   // By acquiring the up lock on the superblock,
  177.   // we prevent it from moving to the global heap.
  178.   // This eventually pins it down in one heap,
  179.   // so this loop is guaranteed to terminate.
  180.   // (It should generally take no more than two iterations.)
  181.   sb->upLock();
  182.   while (1) {
  183.     owner = sb->getOwner();
  184.     owner->lock();
  185.     if (owner == sb->getOwner()) {
  186.       break;
  187.     } else {
  188.       owner->unlock();
  189.     }
  190.     // Suspend to allow ownership to quiesce.
  191.     hoardYield();
  192.   }
  193.  
  194. #if HEAP_LOG
  195.   MemoryRequest m;
  196.   m.free (ptr);
  197.   getLog (owner->getIndex()).append(m);
  198. #endif
  199. #if HEAP_FRAG_STATS
  200.   setDeallocated (b->getRequestedSize(), 0);
  201. #endif
  202.  
  203.   int sbUnmapped = owner->freeBlock (b, sb, sizeclass, this);
  204.  
  205.   owner->unlock();
  206.   if (!sbUnmapped) {
  207.     sb->upUnlock();
  208.   }
  209. }
  210.